package com.layer.client;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.layer.client.event.MsgEvent;
import com.layer.client.event.MsgEventListener;
import com.layer.common.ClientThread;
import com.layer.common.CommunicationInterface;
import com.layer.common.Message;
import com.layer.common.MessageInterface;


public class ClientNode implements CommunicationInterface, MessageInterface {

	private ClientThread client_thread;
	private Logger logger;
	private ArrayList<MsgEventListener> listeners;
	
	public ClientNode(){
		this.logger = LoggerFactory.getLogger(ClientNode.class);
		this.listeners = new ArrayList<MsgEventListener>();
	}

	public void connect() {
		try {
			Socket socket = new Socket("localhost", Integer.valueOf("5432"));
			this.client_thread = new ClientThread(socket, this);
			this.client_thread.start();
			this.logger.info("Client connected at {} local address - {} remote address",socket.getLocalSocketAddress().toString(),socket.getRemoteSocketAddress().toString());
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void disconnect() {
		this.client_thread.disconnect();
	}

	public void sendMessage(Message msg) {
		this.client_thread.send(msg);
	}

	public void receiveMessage(Message msg) {
		switch (msg.getType()) {
		case DISCONNECT_CLIENT:{
			//this.client_thread.closeInputs();
				try {
					this.client_thread.join();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			break;

		default:{
				MsgEvent e = new MsgEvent(msg);
				for (MsgEventListener l : this.listeners) {
					l.handleMsgEvent(e);
				}
			}
			break;
		}
	}

	public synchronized void addEventListener(MsgEventListener l){
		this.listeners.add(l);
		this.listeners.trimToSize();
	}

	public synchronized void removeEventListener(MsgEventListener l){
		this.listeners.remove(l);
		this.listeners.trimToSize();
	}

	public SocketAddress getSocketAddress() {
		// TODO Auto-generated method stub
		return this.client_thread.getSocket().getLocalSocketAddress();
	}
}
